package com.fruit.auth.model;

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.DynamicUpdate;

import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name="AUTH_PRIVILEGE")
@Setter
@Getter
@DynamicUpdate
public class Privilege implements Serializable
{

	private static final long serialVersionUID = -561963571837867333L;
	//权限id
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	
	//权限名称
	@Column(length=64,nullable=false)
	private String name;
	
	//权限关联的url
	private String url;
	
	//权限描述
	private String description;
	
	//是否启用该权限，默认启用
	private Boolean privilegeEnabled=Boolean.TRUE;
	
	//权限类型
	private PrivilegeTypeEnum privilegeType=PrivilegeTypeEnum.FUNCTION;
	
	
	//权限分类,指明该权限是属于那个模块的，比如系统模块,订单模块...
	private String category;
	
	/**
	 * 权限位，意义：与权限码有关，如果没有权限位字段当采用二进制时权限方案时权限码的每一位代表一个权限，所以权限码类似位1,2,4,8,16,32..
	 * Long的值有一个范围，当达到最大值了就不能添加新的权限了，因此使用权限位来解决这个问题，初始权限位位1，权限码达到最大后权限位加1，权限码又从1开始增长
	 * 权限码Long：一个字节有8位，long有8个字节，一个long就有64位，一位代表一个权限，就能表示64个权限
	 * 有一位是符号位 所以一个long能代表63个权限.
	 * 权限位Int：Int有4个字节，32位，一位是符号位 最大为：2的31次方
	 * @see http://blog.csdn.net/gaogaoshan/article/details/12849155
	 */
	@Column(updatable=false)
	private Integer privilegePos;
	
	//权限码,其二进制的每一位代表一个权限,其值类似1,2,4,8，16...
	@Column(updatable=false)
	private Long privilegeCode;
	
	//是否公共资源
	private Boolean isCommon=Boolean.FALSE;
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="pid",updatable=false)
	private Privilege parent;
	
	//子级权限，懒加载,级联添加 更新 删除,删除父级父级权限时子级权限也会同时删除
	@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = CascadeType.ALL)
	private List<Privilege> children;
	
	//父ID,tree使用
	@Transient
	private Integer pid;
	
	public static  enum PrivilegeTypeEnum
	{
		MENU,
		FUNCTION,
		URL,
		BUTTON
		
	}

	public Privilege(Integer id, String name, Boolean privilegeEnabled,
			Privilege parent)
	{
		super();
		this.id = id;
		this.name = name;
		this.privilegeEnabled = privilegeEnabled;
		this.parent = parent;
	}

	public Privilege()
	{
		super();
	}

	
}
